<html><head>
    <title>Texture Demo</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <link rel="stylesheet" href="index_files/webgl.css" type="text/css">
    <script src="js/sylvester.js" type="text/javascript"></script>
    <script src="js/glUtils.js" type="text/javascript"></script>
    <script src = "js/shaderUtils.js" type = "text/javascript"> </script>
    
    <script tyep = "text/javascript">
	
	var canvas;
	var gl;

	var cubeVerticesBuffer;
	var cubeVerticesTextureCoordBuffer;
	var cubeVerticesIndexBuffer;
	var cubeVerticesIndexBuffer;
	var cubeRotation = 0.0;
	var lastCubeUpdateTime = 0;

	var cubeImage;
	var cubeTexture;

	var mvMatrix;
	var perspectiveMatrix;	
	
	
	var webglShader = null;
	
	function start() 
	{
	  canvas = document.getElementById("glcanvas");

	  initWebGL(canvas);      // Initialize the GL context
	  
	  
	  // Only continue if WebGL is available and working
	  
	  if (gl) 
	  {
		gl.clearColor(0.0, 0.0, 0.0, 1.0);  // Clear to black, fully opaque
		gl.clearDepth(1.0);                 // Clear everything
		gl.enable(gl.DEPTH_TEST);           // Enable depth testing
		gl.depthFunc(gl.LEQUAL);            // Near things obscure far things
		
		// Initialize the shaders; this is where all the lighting for the
		// vertices and so forth is established.
		
		webglShader = new WebGLShader();	
		
		webglShader.initShaders(gl);
		
		// Here's where we call the routine that builds all the objects
		// we'll be drawing.
		
		initBuffers();
		
		// Next, load and set up the textures we'll be using.
		
		initTextures();
		
		// Set up to draw the scene periodically.
		
		setInterval(drawScene, 15);
	  }
	}
	
	function initTextures()
	{
		cubeTexture = gl.createTexture();
		cubeImage = new Image();
		cubeImage.onload = function() {handleTextureLoaded(cubeImage, cubeTexture);}  //set callback function
		cubeImage.src = "cubetexture.png";		
	}
	
	function handleTextureLoaded(image, texture)
	{
		gl.bindTexture(gl.TEXTURE_2D, texture);  //set current texture
		gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
		gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
		gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
		gl.generateMipmap(gl.TEXTURE_2D);
		gl.bindTexture(gl.TEXTURE_2D, null); //set current texture null	
	}
	
	//
	// initWebGL
	//
	// Initialize WebGL, returning the GL context or null if
	// WebGL isn't available or could not be initialized.
	//
	function initWebGL()
	{
	  gl = null;
	  
	  try {
		gl = canvas.getContext("experimental-webgl");
	  }
	  catch(e) {
	  }
	  
	  // If we don't have a GL context, give up now
	  
	  if (!gl) {
		alert("Unable to initialize WebGL. Your browser may not support it.");
	  }
	}
	
	//
	// initBuffers
	//
	// Initialize the buffers we'll need. For this demo, we just have
	// one object -- a simple two-dimensional cube.
	//
	function initBuffers() 
	{
	  
	  // Create a buffer for the cube's vertices.
	  
	  cubeVerticesBuffer = gl.createBuffer();
	  
	  // Select the cubeVerticesBuffer as the one to apply vertex
	  // operations to from here out.
	  
	  gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesBuffer);
	  
	  // Now create an array of vertices for the cube.
	  
	  var vertices = [
		// Front face
		-1.0, -1.0,  1.0,
		 1.0, -1.0,  1.0,
		 1.0,  1.0,  1.0,
		-1.0,  1.0,  1.0,
		
		// Back face
		-1.0, -1.0, -1.0,
		-1.0,  1.0, -1.0,
		 1.0,  1.0, -1.0,
		 1.0, -1.0, -1.0,
		
		// Top face
		-1.0,  1.0, -1.0,
		-1.0,  1.0,  1.0,
		 1.0,  1.0,  1.0,
		 1.0,  1.0, -1.0,
		
		// Bottom face
		-1.0, -1.0, -1.0,
		 1.0, -1.0, -1.0,
		 1.0, -1.0,  1.0,
		-1.0, -1.0,  1.0,
		
		// Right face
		 1.0, -1.0, -1.0,
		 1.0,  1.0, -1.0,
		 1.0,  1.0,  1.0,
		 1.0, -1.0,  1.0,
		
		// Left face
		-1.0, -1.0, -1.0,
		-1.0, -1.0,  1.0,
		-1.0,  1.0,  1.0,
		-1.0,  1.0, -1.0
	  ];
	  
	  // Now pass the list of vertices into WebGL to build the shape. We
	  // do this by creating a Float32Array from the JavaScript array,
	  // then use it to fill the current vertex buffer.
	  
	  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

	  // Map the texture onto the cube's faces.
	  
	  cubeVerticesTextureCoordBuffer = gl.createBuffer();
	  gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesTextureCoordBuffer);
	  
	  var textureCoordinates = [
		// Front
		0.0,  0.0,
		1.0,  0.0,
		1.0,  1.0,
		0.0,  1.0,
		// Back
		0.0,  0.0,
		1.0,  0.0,
		1.0,  1.0,
		0.0,  1.0,
		// Top
		0.0,  0.0,
		1.0,  0.0,
		1.0,  1.0,
		0.0,  1.0,
		// Bottom
		0.0,  0.0,
		1.0,  0.0,
		1.0,  1.0,
		0.0,  1.0,
		// Right
		0.0,  0.0,
		1.0,  0.0,
		1.0,  1.0,
		0.0,  1.0,
		// Left
		0.0,  0.0,
		1.0,  0.0,
		1.0,  1.0,
		0.0,  1.0
	  ];

	  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates),
					gl.STATIC_DRAW);

	  // Build the element array buffer; this specifies the indices
	  // into the vertex array for each face's vertices.
	  
	  cubeVerticesIndexBuffer = gl.createBuffer();
	  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVerticesIndexBuffer);
	  
	  // This array defines each face as two triangles, using the
	  // indices into the vertex array to specify each triangle's
	  // position.
	  
	  var cubeVertexIndices = [
		0,  1,  2,      0,  2,  3,    // front
		4,  5,  6,      4,  6,  7,    // back
		8,  9,  10,     8,  10, 11,   // top
		12, 13, 14,     12, 14, 15,   // bottom
		16, 17, 18,     16, 18, 19,   // right
		20, 21, 22,     20, 22, 23    // left
	  ]
	  
	  // Now send the element array to GL
	  
	  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
		  new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW);
	}
	
	//
	// drawScene
	//
	// Draw the scene.
	//
	function drawScene() 
	{
	  // Clear the canvas before we start drawing on it.

	  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
	  
	  // Establish the perspective with which we want to view the
	  // scene. Our field of view is 45 degrees, with a width/height
	  // ratio of 640:480, and we only want to see objects between 0.1 units
	  // and 100 units away from the camera.
	  
	  perspectiveMatrix = makePerspective(45, 640.0/480.0, 0.1, 100.0);
	  
	  // Set the drawing position to the "identity" point, which is
	  // the center of the scene.
	  
	  loadIdentity();
	  
	  // Now move the drawing position a bit to where we want to start
	  // drawing the cube.
	  
	  mvTranslate([-0.0, 0.0, -6.0]);
	  
	  // Save the current matrix, then rotate before we draw.
	  
	  mvPushMatrix();
	  mvRotate(cubeRotation, [1, 0, 1]);
	  
	  // Draw the cube by binding the array buffer to the cube's vertices
	  // array, setting attributes, and pushing it to GL.
	  
	  gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesBuffer);
	  gl.vertexAttribPointer(webglShader.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
	  
	  // Set the texture coordinates attribute for the vertices.
	  
	  gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesTextureCoordBuffer);
	  gl.vertexAttribPointer(webglShader.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
	  
	  // Specify the texture to map onto the faces.
	  gl.activeTexture(gl.TEXTURE0);
	  gl.bindTexture(gl.TEXTURE_2D, cubeTexture);
	  gl.uniform1i(gl.getUniformLocation(webglShader.shaderProgram, "uSampler"), 0);
	  
	  
	
	  
	  // Draw the cube.
	  
	  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVerticesIndexBuffer);
	  setMatrixUniforms();
	  gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0);
	  
	  // Restore the original matrix
	  
	  mvPopMatrix();
	  
	  // Update the rotation for the next draw, if it's time to do so.
	  
	  var currentTime = (new Date).getTime();
	  if (lastCubeUpdateTime) {
		var delta = currentTime - lastCubeUpdateTime;
		
		cubeRotation += (30 * delta) / 1000.0;
	  }
	  
	  lastCubeUpdateTime = currentTime;
	}
	
	
    </script>
    
    <script src="js/shaderUtils.js" type="text/javascript"></script>
    <script src="js/matrixUtils.js" type="text/javascript"></script>
   
    

    <!-- Fragment shader program -->

    <script id="shader-fs" type="x-shader/x-fragment">
      varying highp vec2 vTextureCoord;
      
      uniform sampler2D uSampler;
      
      void main(void) {
        gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
      }
    </script>
    
    <!-- Vertex shader program -->
    
    <script id="shader-vs" type="x-shader/x-vertex">
      attribute vec3 aVertexPosition;
      attribute vec2 aTextureCoord;
    
      uniform mat4 uMVMatrix;
      uniform mat4 uPMatrix;
      
      varying highp vec2 vTextureCoord;
    
      void main(void) {
        gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
        vTextureCoord = aTextureCoord;
      }
    </script>
  </head>
  
  <body onload="start()">
    <canvas id="glcanvas" width="960" height="540">
      Your browser doesn't appear to support the HTML5 <code>&lt;canvas&gt;</code> element.
    </canvas>
  
</body></html>
